package com.stylefeng.guns.modular.utils;

import com.stylefeng.guns.common.persistence.model.ProjectTable;
import com.stylefeng.guns.common.persistence.model.ProjectTableProperty;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.List;

import static org.aspectj.weaver.tools.cache.SimpleCacheFactory.path;

/**
 * @author lmshe
 * @create 2018-07-06 16:51
 * @desc
 */
public class GeneratorUtils {

    public static final String MAPPING_PATH = "E:/myself/project/park_management/SP.Data/Mapping";

    public static final String DOMAIN_PATH = "E:/myself/project/park_management/SP.Data/Domain";

    public static final String VIEW_MODELS_PATH = "E:/myself/project/park_management/SP.Models/ViewModels";

    public static final String SEARCH_MODELS_PATH = "E:/myself/project/park_management/SP.Models/SearchModels";

    public static final String ISERVICE_PATH = "E:/myself/project/park_management/SP.Services";

    public static final String SERVICE_IMPL_PATH = "E:/myself/project/park_management/SP.Services.Impl";

    public static final String PROFILES_PATH = "E:/myself/project/park_management/SP.Services.Impl/Extensions/Profiles";

    public static final String CONTROLLER_PATH = "E:/myself/project/park_management/SP.Web/Controllers";

    public static final String VIEW_PATH = "E:/myself/project/park_management/SP.Web/Views";

    //生成mapping
    public static void generatorMapping(List<ProjectTableProperty> projectTablePropertyList, ProjectTable projectTable) {
        try {
            String tableName = projectTable.getTableName();
            //创建目录
            checkPath(MAPPING_PATH);
            //判断文件是否已经存在
            File file = new File(MAPPING_PATH + "/" + initcap(tableName) + "Map.cs");
            if (checkFile(file)) {
                return;
            }
            //拼接内容字符串
            StringBuffer sb = new StringBuffer();
            sb.append("using System;\r\n");
            sb.append("using System.Collections.Generic;\r\n");
            sb.append("using System.ComponentModel.DataAnnotations.Schema;\r\n");
            sb.append("using System.Data.Entity.Infrastructure.Annotations;\r\n");
            sb.append("using System.Linq;\r\n");
            sb.append("using System.Text;\r\n");
            sb.append("using System.Threading.Tasks;\r\n\r\n");

            sb.append("namespace SP.Data.Mapping\r\n");
            sb.append("{\r\n");
            sb.append("    /// <summary>\r\n");
            sb.append("    /// " + projectTable.getTableDesc() + "\r\n");
            sb.append("    /// </summary>\r\n");
            sb.append("    public class " + initcap(tableName) + "Map : BaseEntityTypeConfiguration<" + initcap(tableName) + ">\r\n");
            sb.append("    {\r\n");
            sb.append("        public " + initcap(tableName) + "Map()\r\n");
            sb.append("        {\r\n");
            sb.append("            this.ToTable(\"" + initcap(tableName) + "\");\r\n");

            sb.append("            this.HasKey(p => p.Id);\r\n");
            sb.append("            this.Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);\r\n");
            for (ProjectTableProperty ptp : projectTablePropertyList) {
                String codeType = ptp.getCodeType();
                if ("DateTime".equals(codeType)) {//时间类型
                    sb.append("            this.Property(p => p." + initcap(ptp.getENName()) + ")" + (ptp.getIsNull() == 1 ? "" : ".IsRequired()") + ";\r\n");
                } else if ("int".equals(codeType)) {//int类型
                    sb.append("            this.Property(p => p." + initcap(ptp.getENName()) + ")" + (ptp.getIsNull() == 1 ? "" : ".IsRequired()") + ";\r\n");
                } else {//其他类型全部当作String
                    sb.append("            this.Property(p => p." + initcap(ptp.getENName()) + ")" + ".HasMaxLength(" + ptp.getLength() + ")" + (ptp.getIsNull() == 1 ? "" : ".IsRequired()") + ";\r\n");
                }
            }
            sb.append("        }\r\n");
            sb.append("    }\r\n");
            sb.append("}\r\n");
            writeStringToFile(file, sb.toString());
            //修改csproj
            String csprojPath = "E:\\myself\\project\\park_management\\SP.Data\\SP.Data.csproj";
            String changeContent = "<Compile Include=\"Mapping\\"+ initcap(tableName) +"Map.cs\" />\r\n";
            String key = "\"Mapping\\" + initcap(tableName) +"Map.cs\"";
            ModifyCsproj.modifyCsproj(csprojPath,changeContent,key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //生成实体对象
    public static void generatorDomain(List<ProjectTableProperty> projectTablePropertyList, ProjectTable projectTable) {
        try {
            String tableName = projectTable.getTableName();
            //创建目录
            checkPath(DOMAIN_PATH);
            //判断文件是否已经存在
            File file = new File(DOMAIN_PATH + "/" + initcap(tableName) + ".cs");
            if (checkFile(file)) {
                return;
            }
            //拼接内容字符串
            StringBuffer sb = new StringBuffer();
            sb.append("using SP.Infrastructure.Enums;\r\n");
            sb.append("using System;\r\n");
            sb.append("using System.Collections.Generic;\r\n");
            sb.append("using System.Linq;\r\n");
            sb.append("using System.Text;\r\n");
            sb.append("using System.Threading.Tasks;\r\n");

            sb.append("namespace SP.Data\r\n");
            sb.append("{\r\n");
            sb.append("    /// <summary>\r\n");
            sb.append("    /// " + projectTable.getTableDesc() + "\r\n");
            sb.append("    /// </summary>\r\n");
            sb.append("    public class " + initcap(tableName) + " : BaseEntity\r\n");
            sb.append("    {\r\n");
            for (ProjectTableProperty ptp : projectTablePropertyList) {
                sb.append("        /// <summary>\r\n");
                sb.append("        /// " + ptp.getCNName() + "\r\n");
                sb.append("        /// </summary>\r\n");

                String codeType = ptp.getCodeType();
                if ("DateTime".equals(codeType)) {//时间类型
                    sb.append("       public DateTime" + (ptp.getIsNull() == 1 ? "?" : "") + " " + initcap(ptp.getENName()) + " { get; set; }\r\n");
                } else if ("int".equals(codeType)) {//int类型
                    sb.append("       public int" + (ptp.getIsNull() == 1 ? "?" : "") + " " + initcap(ptp.getENName()) + " { get; set; }\r\n");
                } else {//其他类型全部当作String
                    sb.append("       public string " + initcap(ptp.getENName()) + " { get; set; }\r\n");
                }
            }
            sb.append("    }\r\n");
            sb.append("}\r\n");
            writeStringToFile(file, sb.toString());
            //修改csproj
            String csprojPath = "E:\\myself\\project\\park_management\\SP.Data\\SP.Data.csproj";
            String changeContent = "<Compile Include=\"Domain\\"+ initcap(tableName) +".cs\" />\r\n";
            String key = "\"Domain\\" + initcap(tableName) +".cs\"";
            ModifyCsproj.modifyCsproj(csprojPath,changeContent,key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //生成视图
    public static void generatorViewModel(List<ProjectTableProperty> projectTablePropertyList, ProjectTable projectTable) {
        try {
            String tableName = projectTable.getTableName();
            //创建目录
            checkPath(VIEW_MODELS_PATH);
            //判断文件是否已经存在
            File file = new File(VIEW_MODELS_PATH + "/" + initcap(tableName) + "Model.cs");
            if (checkFile(file)) {
                return;
            }
            //拼接内容字符串
            StringBuffer sb = new StringBuffer();
            sb.append("using SP.Infrastructure.Enums;\r\n");
            sb.append("using System;\r\n");
            sb.append("using System.Collections.Generic;\r\n");
            sb.append("using System.Linq;\r\n");
            sb.append("using System.Text;\r\n");
            sb.append("using System.Threading.Tasks;\r\n");

            sb.append("namespace SP.Models.ViewModels\r\n");
            sb.append("{\r\n");
            sb.append("    /// <summary>\r\n");
            sb.append("    /// " + projectTable.getTableDesc() + "\r\n");
            sb.append("    /// </summary>\r\n");
            sb.append("    public class " + initcap(tableName) + "Model : BaseModel\r\n");
            sb.append("    {\r\n");
            for (ProjectTableProperty ptp : projectTablePropertyList) {
                sb.append("        /// <summary>\r\n");
                sb.append("        /// " + ptp.getCNName() + "\r\n");
                sb.append("        /// </summary>\r\n");

                String codeType = ptp.getCodeType();
                if ("DateTime".equals(codeType)) {//时间类型
                    sb.append("       public DateTime" + (ptp.getIsNull() == 1 ? "?" : "") + " " + initcap(ptp.getENName()) + " { get; set; }\r\n");
                } else if ("int".equals(codeType)) {//int类型
                    sb.append("       public int" + (ptp.getIsNull() == 1 ? "?" : "") + " " + initcap(ptp.getENName()) + " { get; set; }\r\n");
                } else {//其他类型全部当作String
                    sb.append("       public string " + initcap(ptp.getENName()) + " { get; set; }\r\n");
                }
            }
            sb.append("    }\r\n");
            sb.append("}\r\n");
            writeStringToFile(file, sb.toString());
            //修改csproj
            String csprojPath = "E:\\myself\\project\\park_management\\SP.Models\\SP.Models.csproj";
            String changeContent = "<Compile Include=\"ViewModels\\"+ initcap(tableName) +"Model.cs\" />\r\n";
            String key = "\"ViewModels\\" + initcap(tableName) +"Model.cs\"";
            ModifyCsproj.modifyCsproj(csprojPath,changeContent,key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //生成查询条件model
    public static void generatorSearchModel(ProjectTable projectTable) {
        try {
            String tableName = projectTable.getTableName();
            //创建目录
            checkPath(SEARCH_MODELS_PATH);
            //判断文件是否已经存在
            File file = new File(SEARCH_MODELS_PATH + "/" + initcap(tableName) + "SearchModel.cs");
            if (checkFile(file)) {
                return;
            }
            //拼接内容字符串
            StringBuffer sb = new StringBuffer();
            sb.append("using SP.Infrastructure.Enums;\r\n");
            sb.append("using System;\r\n");
            sb.append("using System.Collections.Generic;\r\n");
            sb.append("using System.Linq;\r\n");
            sb.append("using System.Text;\r\n");
            sb.append("using System.Threading.Tasks;\r\n");
            sb.append("namespace SP.Models.SearchModels\r\n");
            sb.append("{\r\n");
            sb.append("    /// <summary>\r\n");
            sb.append("    /// " + projectTable.getTableDesc() + "查询模型\r\n");
            sb.append("    /// </summary>\r\n");
            sb.append("    public class " + initcap(tableName) + "SearchModel\r\n");
            sb.append("    {\r\n");
            sb.append("        public List<FilterDescriptor> ToFilters()\r\n");
            sb.append("        {\r\n");
            sb.append("            List<FilterDescriptor> list = new List<FilterDescriptor>();\r\n");
            sb.append("            list.Add(new FilterDescriptor() { Member = \"IsDeleted\", Operator = FilterOperator.IsEqualTo, Value = false });\r\n");
            sb.append("            return list;\r\n");
            sb.append("        }\r\n");
            sb.append("        public List<SortDescriptor> ToSorts()\r\n");
            sb.append("        {\r\n");
            sb.append("            List<SortDescriptor> list = new List<SortDescriptor>();\r\n");
            sb.append("            list.Add(new SortDescriptor\r\n");
            sb.append("            {\r\n");
            sb.append("                Member = \"Id\",\r\n");
            sb.append("                SortDirection = ListSortDirection.Descending\r\n");
            sb.append("            });\r\n");
            sb.append("            return list;\r\n");
            sb.append("        }\r\n");
            sb.append("    }\r\n");
            sb.append("}\r\n");
            writeStringToFile(file,sb.toString());
            //修改csproj
            String csprojPath = "E:\\myself\\project\\park_management\\SP.Models\\SP.Models.csproj";
            String changeContent = "<Compile Include=\"SearchModels\\"+ initcap(tableName) +"SearchModel.cs\" />\r\n";
            String key = "\"SearchModels\\" + initcap(tableName) +"SearchModel.cs\"";
            ModifyCsproj.modifyCsproj(csprojPath,changeContent,key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //生成Service
    public static void generatorServices(ProjectTable projectTable) {
        try {
            String tableName = projectTable.getTableName();
            String modelStr = initcap(tableName) + "Model";
            //创建目录
            checkPath(ISERVICE_PATH);
            //判断文件是否已经存在
            File file = new File(ISERVICE_PATH + "/I" + initcap(tableName) + "Service.cs");
            if (!checkFile(file)) {
                //拼接内容字符串
                StringBuffer iService = new StringBuffer();
                iService.append("using SP.Models;\r\n");
                iService.append("using SP.Models.SearchModels;\r\n");
                iService.append("using SP.Models.ViewModels;\r\n");
                iService.append("using System;\r\n");
                iService.append("using System.Collections.Generic;\r\n");
                iService.append("using System.Linq;\r\n");
                iService.append("using System.Text;\r\n");
                iService.append("using System.Threading.Tasks;\r\n");
                iService.append("namespace SP.Services\r\n");
                iService.append("{\r\n");
                iService.append("    public interface I" + initcap(tableName) + "Service\r\n");
                iService.append("    {\r\n");
                iService.append("        ApiListResult<" + modelStr + "> Search(SearchModel searchModel);\r\n");
                iService.append("        ApiResult<" + modelStr + "> GetById(int id);\r\n");
                iService.append("        ApiResult<" + modelStr + "> Create(" + modelStr + " model);\r\n");
                iService.append("        ApiResult<" + modelStr + "> Update(" + modelStr + " model);\r\n");
                iService.append("        ApiResult<bool> Delete(int id);\r\n");
                iService.append("    }\r\n");
                iService.append("}\r\n");
                writeStringToFile(file, iService.toString());
                //修改csproj
                String csprojPath = "E:\\myself\\project\\park_management\\SP.Services\\SP.Services.csproj";
                String changeContent = "<Compile Include=\"I"+ initcap(tableName) +"Service.cs\" />\r\n";
                String key = "\"I"+initcap(tableName) +"Service.cs\"";
                ModifyCsproj.modifyCsproj(csprojPath,changeContent,key);
            }
            //创建目录
            checkPath(SERVICE_IMPL_PATH);
            //判断文件是否已经存在
            File serviceImplFile = new File(SERVICE_IMPL_PATH + "/" + initcap(tableName) + "Service.cs");
            if (!checkFile(serviceImplFile)) {
                StringBuffer serviceImpl = new StringBuffer();
                serviceImpl.append("using SP.Data;\r\n");
                serviceImpl.append("using SP.Models;\r\n");
                serviceImpl.append("using SP.Models.ViewModels;\r\n");
                serviceImpl.append("using Microsoft.AspNet.Identity;\r\n");
                serviceImpl.append("using Microsoft.AspNet.Identity.EntityFramework;\r\n");
                serviceImpl.append("using Microsoft.AspNet.Identity.Owin;\r\n");
                serviceImpl.append("using System;\r\n");
                serviceImpl.append("using System.Collections.Generic;\r\n");
                serviceImpl.append("using System.Linq;\r\n");
                serviceImpl.append("using System.Text;\r\n");
                serviceImpl.append("using System.Threading.Tasks;\r\n");
                serviceImpl.append("using SP.Infrastructure.Enums;\r\n");
                serviceImpl.append("using SP.Infrastructure.Utils;\r\n");
                serviceImpl.append("using SP.Infrastructure.Security;\r\n");
                serviceImpl.append("using SP.Models.SearchModels;\r\n");

                serviceImpl.append("namespace SP.Services.Impl\r\n");
                serviceImpl.append("{\r\n");
                serviceImpl.append("    public class " + initcap(tableName) + "Service : EntityService<" + initcap(tableName) + ", int, " + initcap(tableName) + "Model>, I" + initcap(tableName) + "Service\r\n");
                serviceImpl.append("    {\r\n");

                serviceImpl.append("        public " + initcap(tableName) + "Service() : base()\r\n");
                serviceImpl.append("        {\r\n");

                serviceImpl.append("        }\r\n");

                serviceImpl.append("        public " + initcap(tableName) + "Service(IAppDbContext context) : base(context)\r\n");
                serviceImpl.append("        {\r\n");

                serviceImpl.append("        }\r\n");
                serviceImpl.append("        /// <summary>\r\n");
                serviceImpl.append("        /// 根据Id查询\r\n");
                serviceImpl.append("        /// </summary>\r\n");
                serviceImpl.append("        /// <param name=\"id\"></param>\r\n");
                serviceImpl.append("        /// <returns></returns>\r\n");
                serviceImpl.append("        public override ApiResult<" + initcap(tableName) + "Model> GetById(int id)\r\n");
                serviceImpl.append("        {\r\n");
                serviceImpl.append("            return Get<" + initcap(tableName) + "Model>(p => p.Id == id && p.IsDeleted == false);\r\n");
                serviceImpl.append("        }\r\n");

                serviceImpl.append("        /// <summary>\r\n");
                serviceImpl.append("        /// 新增\r\n");
                serviceImpl.append("        /// </summary>\r\n");
                serviceImpl.append("        /// <param name=\"model\"></param>\r\n");
                serviceImpl.append("        /// <returns></returns>\r\n");
                serviceImpl.append("        public override ApiResult<" + initcap(tableName) + "Model> Create(" + initcap(tableName) + "Model model)\r\n");
                serviceImpl.append("        {\r\n");
                serviceImpl.append("            //添加\r\n");
                serviceImpl.append("           return Create<" + initcap(tableName) + "Model>(model, entity =>\r\n");
                serviceImpl.append("           {\r\n");
                serviceImpl.append("                entity.IsDeleted = false;\r\n");
                serviceImpl.append("                entity.CreatedTime = DateTime.Now;\r\n");
                serviceImpl.append("                entity.CreatedBy = model.CreatedBy;\r\n");
                serviceImpl.append("                entity.UpdatedTime = DateTime.Now;\r\n");
                serviceImpl.append("                entity.UpdatedBy = model.UpdatedBy;\r\n");
                serviceImpl.append("            });\r\n");
                serviceImpl.append("        }\r\n");

                serviceImpl.append("        /// <summary>\r\n");
                serviceImpl.append("        /// 更新\r\n");
                serviceImpl.append("        /// </summary>\r\n");
                serviceImpl.append("        /// <param name=\"model\"></param>\r\n");
                serviceImpl.append("        /// <returns></returns>\r\n");
                serviceImpl.append("        public override ApiResult<" + initcap(tableName) + "Model> Update(" + initcap(tableName) + "Model model)\r\n");
                serviceImpl.append("        {\r\n");
                serviceImpl.append("            return Update<" + initcap(tableName) + "Model>(model);\r\n");
                serviceImpl.append("        }\r\n");
                serviceImpl.append("    }\r\n");
                serviceImpl.append("}\r\n");
                writeStringToFile(serviceImplFile, serviceImpl.toString());
                //修改csproj
                String csprojPath = "E:\\myself\\project\\park_management\\SP.Services.Impl\\SP.Services.Impl.csproj";
                String changeContent = "<Compile Include=\""+ initcap(tableName) +"Service.cs\" />\r\n";
                String key = "\"" + initcap(tableName) +"Service.cs\"";
                ModifyCsproj.modifyCsproj(csprojPath,changeContent,key);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //生成profile
    public static void generatorProfiles(ProjectTable projectTable) {
        try {
            String tableName = projectTable.getTableName();
            //创建目录
            checkPath(PROFILES_PATH);
            //判断文件是否已经存在
            File file = new File(PROFILES_PATH + "/" + initcap(tableName) + "Profile.cs");
            if (checkFile(file)) {
                return;
            }
            //拼接内容字符串
            StringBuffer sb = new StringBuffer();
            sb.append("using AutoMapper;\r\n");
            sb.append("using SP.Data;\r\n");
            sb.append("using SP.Models.ViewModels;\r\n");
            sb.append("using System;\r\n");
            sb.append("using System.Collections.Generic;\r\n");
            sb.append("using System.Linq;\r\n");
            sb.append("using System.Text;\r\n");
            sb.append("using System.Threading.Tasks;\r\n");

            sb.append("namespace SP.Services.Impl.Extensions.Profiles\r\n");
            sb.append("{\r\n");
            sb.append("    public class " + initcap(tableName) + "Profile : Profile\r\n");
            sb.append("    {\r\n");
            sb.append("        public " + initcap(tableName) + "Profile()\r\n");
            sb.append("        {\r\n");
            sb.append("            CreateMap<" + initcap(tableName) + "Model, " + initcap(tableName) + ">()\r\n");
            sb.append("            .ForMember(p => p.CreatedBy, opt => opt.Ignore())\r\n");
            sb.append("            .ForMember(p => p.CreatedTime, opt => opt.Ignore());\r\n");

            sb.append("            CreateMap<" + initcap(tableName) + ", " + initcap(tableName) + "Model>();\r\n");
            sb.append("        }\r\n");
            sb.append("    }\r\n");
            sb.append("}\r\n");
            writeStringToFile(file, sb.toString());
            //修改csproj
            String csprojPath = "E:\\myself\\project\\park_management\\SP.Services.Impl\\SP.Services.Impl.csproj";
            String changeContent = "<Compile Include=\"Extensions\\Profiles\\"+initcap(tableName)+"Profile.cs\" />\r\n";
            String key = "\"Extensions\\Profiles\\" + initcap(tableName) +"Profile.cs";
            ModifyCsproj.modifyCsproj(csprojPath,changeContent,key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //生成controller
    public static void generatorController(ProjectTable projectTable) {
        try {
            String tableName = projectTable.getTableName();
            //创建目录
            checkPath(CONTROLLER_PATH);
            //判断文件是否已经存在
            File file = new File(CONTROLLER_PATH + "/" + initcap(tableName) + "Controller.cs");
            if (checkFile(file)) {
                return;
            }
            //拼接内容字符串
            StringBuffer sb = new StringBuffer();
            sb.append("using Microsoft.AspNet.Identity;\r\n");
            sb.append("using Microsoft.Owin.Security;\r\n");
            sb.append("using System;\r\n");
            sb.append("using System.Collections.Generic;\r\n");
            sb.append("using System.Linq;\r\n");
            sb.append("using System.Threading.Tasks;\r\n");
            sb.append("using System.Web;\r\n");
            sb.append("using System.Web.Mvc;\r\n");
            sb.append("using SP.Models.ViewModels;\r\n");
            sb.append("using SP.Services;\r\n");
            sb.append("using SP.Models;\r\n");
            sb.append("using Kendo.Mvc.UI;\r\n");
            sb.append("using SP.Models.SearchModels;\r\n");
            sb.append("using SP.Web.Attributes;\r\n");
            sb.append("using SP.Infrastructure.Enums;\r\n");

            sb.append("namespace SP.Web.Controllers\r\n");
            sb.append("{\r\n");
            sb.append("    [Authorize]\r\n");
            sb.append("    /// <summary>\r\n");
            sb.append("    /// " + projectTable.getTableDesc() + "\r\n");
            sb.append("    /// </summary>\r\n");
            sb.append("    public class " + initcap(tableName) + "Controller : Controller\r\n");
            sb.append("    {\r\n");
            sb.append("        private I" + initcap(tableName) + "Service " + initcap(tableName) + "Service { get; set; }\r\n");

            sb.append("        public " + initcap(tableName) + "Controller(I" + initcap(tableName) + "Service " + getCamelStr(tableName) + "Service)\r\n");
            sb.append("        {\r\n");
            sb.append("            " + initcap(tableName) + "Service = " + getCamelStr(tableName) + "Service;\r\n");
            sb.append("        }\r\n");

            sb.append("        #region 列表\r\n");
            sb.append("        [CustomAuthorize(\"" + initcap(tableName) + "Page\")]\r\n");
            sb.append("        public ActionResult Index()\r\n");
            sb.append("        {\r\n");
            sb.append("            return View();\r\n");
            sb.append("        }\r\n");

            sb.append("        /// <summary>\r\n");
            sb.append("        /// 获取分页列表\r\n");
            sb.append("        /// </summary>\r\n");
            sb.append("        /// <param name=\"request\"></param>\r\n");
            sb.append("        /// <returns></returns>\r\n");
            sb.append("        public ActionResult GetList([DataSourceRequest]DataSourceRequest request, " + initcap(tableName) + "SearchModel model)\r\n");
            sb.append("        {\r\n");
            sb.append("            SearchModel searchModel = new SearchModel\r\n");
            sb.append("            {\r\n");
            sb.append("                PageNo = request.Page,\r\n");
            sb.append("                PageSize = request.PageSize\r\n");
            sb.append("            };\r\n");
            sb.append("            searchModel.Filters = model.ToFilters();\r\n");
            sb.append("            searchModel.Sorts = model.ToSorts();\r\n");
            sb.append("            ApiListResult<" + initcap(tableName) + "Model> apiListResult = " + initcap(tableName) + "Service.Search(searchModel);\r\n");
            sb.append("            return Json(apiListResult.ToDataSourceResult());\r\n");
            sb.append("        }\r\n");

            sb.append("        #endregion\r\n");

            sb.append("        #region 新增/修改\r\n");

            sb.append("        /// <summary>\r\n");
            sb.append("        /// 展示创建页面\r\n");
            sb.append("        /// </summary>\r\n");
            sb.append("        /// <returns></returns>\r\n");
            sb.append("        [HttpGet]\r\n");
            sb.append("        public ActionResult Create()\r\n");
            sb.append("        {\r\n");
            sb.append("            " + initcap(tableName) + "Model viewModel = new " + initcap(tableName) + "Model();\r\n");
            sb.append("            return View(\"Edit\", viewModel);\r\n");
            sb.append("        }\r\n");

            sb.append("        /// <summary>\r\n");
            sb.append("        /// 展示编辑页面\r\n");
            sb.append("        /// </summary>\r\n");
            sb.append("        /// <param name=\"id\"></param>\r\n");
            sb.append("        /// <returns></returns>\r\n");
            sb.append("        [HttpGet]\r\n");
            sb.append("        public ActionResult Edit(int id)\r\n");
            sb.append("        {\r\n");
            sb.append("            " + initcap(tableName) + "Model viewModel = " + initcap(tableName) + "Service.GetById(id).Result;\r\n");
            sb.append("            return View(viewModel);\r\n");
            sb.append("        }\r\n");

            sb.append("        /// <summary>\r\n");
            sb.append("        /// 处理创建和编辑页面\r\n");
            sb.append("        /// </summary>\r\n");
            sb.append("        /// <returns></returns>\r\n");
            sb.append("        [HttpPost]\r\n");
            sb.append("        public ActionResult Edit(" + initcap(tableName) + "Model model)\r\n");
            sb.append("        {\r\n");
            sb.append("            ApiResult<" + initcap(tableName) + "Model> result;\r\n");
            sb.append("            if (model.Id == 0)\r\n");
            sb.append("            {\r\n");
            sb.append("                //新增\r\n");
            sb.append("                model.CreatedBy = User.Identity.Name;\r\n");
            sb.append("                result = " + initcap(tableName) + "Service.Create(model);\r\n");
            sb.append("                if (result.ResultCode != \"0\")\r\n");
            sb.append("                {\r\n");
            sb.append("                    ModelState.AddModelError(\"\", result.ErrorMessage);\r\n");
            sb.append("                    return View(model);\r\n");
            sb.append("                }\r\n");
            sb.append("            }\r\n");
            sb.append("            else\r\n");
            sb.append("            {\r\n");
            sb.append("                //修改\r\n");
            sb.append("                model.UpdatedBy = User.Identity.Name;\r\n");
            sb.append("                result = " + initcap(tableName) + "Service.Update(model);\r\n");
            sb.append("                if (result.ResultCode != \"0\")\r\n");
            sb.append("                {\r\n");
            sb.append("                    ModelState.AddModelError(\"\", result.ErrorMessage);\r\n");
            sb.append("                    return View(model);\r\n");
            sb.append("                }\r\n");
            sb.append("            }\r\n");
            sb.append("            return RedirectToAction(\"Index\");\r\n");
            sb.append("        }\r\n");

            sb.append("        #endregion\r\n");

            sb.append("        #region 删除\r\n");

            sb.append("        /// <summary>\r\n");
            sb.append("        /// 处理删除\r\n");
            sb.append("        /// </summary>\r\n");
            sb.append("        /// <param name=\"id\"></param>\r\n");
            sb.append("        /// <returns></returns>\r\n");
            sb.append("        [HttpPost]\r\n");
            sb.append("        public ActionResult Delete(int id)\r\n");
            sb.append("        {\r\n");
            sb.append("            ApiResult<bool> result = " + initcap(tableName) + "Service.Delete(id);\r\n");
            sb.append("            if (result.Result)\r\n");
            sb.append("            {\r\n");
            sb.append("                return RedirectToAction(\"Index\");\r\n");
            sb.append("            }\r\n");
            sb.append("            else\r\n");
            sb.append("            {\r\n");
            sb.append("                return JavaScript($\"alert('{result.ErrorMessage}')\");\r\n");
            sb.append("            }\r\n");
            sb.append("        }\r\n");
            sb.append("        #endregion\r\n");
            sb.append("    }\r\n");
            sb.append("}\r\n");
            writeStringToFile(file, sb.toString());
            //修改csproj
            String csprojPath = "E:\\myself\\project\\park_management\\SP.Web\\SP.Web.csproj";
            String changeContent = "<Compile Include=\"Controllers\\"+initcap(tableName) +"Controller.cs\" />\r\n";
            String key = "\"Controllers\\" + initcap(tableName) +"Controller.cs";
            ModifyCsproj.modifyCsproj(csprojPath,changeContent,key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //生成视图
    public static void generatorViews(List<ProjectTableProperty> projectTablePropertyList, ProjectTable projectTable) {
        try {
            String tableName = projectTable.getTableName();
            String path = VIEW_PATH + "/" + initcap(tableName);
            //创建目录
            checkPath(path);

            //判断文件是否已经存在
            File index = new File(path + "/Index.cshtml");
            if (!checkFile(index)) {
                //拼接内容字符串
                StringBuffer sb = new StringBuffer();
                sb.append("@model " + initcap(tableName) + "SearchModel\r\n");
                sb.append("@{\r\n");
                sb.append("    ViewBag.Title = \"" + projectTable.getTableDesc() + "\";\r\n");
                sb.append("}\r\n");

                sb.append("<input type=\"hidden\" value=\"" + initcap(tableName) + "Page\" id=\"menutag\" />\r\n");
                sb.append("<div class=\"cont-header form-inline\">\r\n");
                sb.append("    <div class=\"pull-left\">\r\n");
                sb.append("        @ViewBag.Title\r\n");
                sb.append("    </div>\r\n");
                sb.append("    <div class=\"form-group pull-right\">\r\n");
                sb.append("        <a class=\"k-primary k-button\" href=\"@Url.Action(\"Create\",\"" + initcap(tableName) + "\")\">新增</a>\r\n");
                sb.append("    </div>\r\n");
                sb.append("</div>\r\n");
                sb.append("<div class=\"box box-solid\">\r\n");
                sb.append("    <div class=\"box-body\">\r\n");
                sb.append("        <div class=\"searchIframe form-inline clearfix\">\r\n");

                sb.append("        </div>\r\n");
                sb.append("        @(Html.Kendo().Grid<" + initcap(tableName) + "Model>()\r\n");
                sb.append("            .Name(\"grid\")\r\n");
                sb.append("            .Columns(columns =>\r\n");
                sb.append("            {\r\n");
                for (ProjectTableProperty ptp : projectTablePropertyList) {
                    String codeType = ptp.getCodeType();
                    if ("DateTime".equals(codeType)) {//时间类型
                        sb.append("                columns.Bound(p => p." + initcap(ptp.getENName()) + ").Title(\"" + ptp.getCNName() + "\").Format(\"{0:yyyy-MM-dd HH:mm:ss}\").HtmlAttributes(new { style = \"white-space:nowrap;\" });\r\n");
                    } else {//其他类型全部当作String
                        sb.append("                columns.Bound(p => p." + initcap(ptp.getENName()) + ").Title(\"" + ptp.getCNName() + "\").HtmlAttributes(new { style = \"white-space:nowrap;\" });\r\n");
                    }
                }
                sb.append("                columns.Bound(p => p.Id).Title(\"操作\").Width(240)\r\n");
                sb.append("                .ClientTemplate(\r\n");
                sb.append("                    @\"<a href=\" + Url.Action(\"Edit\", \"" + initcap(tableName) + "\") + \"/#: Id #\" + \" type='button' class='k-button k-grid-edit' style='margin-right:5px;'>编辑</a>\" +\r\n");
                sb.append("                    \"<button class='k-button k-grid-delete' onclick='del(\" + \"#:Id #\" + \")'>删除</button>\");\r\n");
                sb.append("            })\r\n");
                sb.append("            .HtmlAttributes(new { style = \"height:600px;\" })\r\n");
                sb.append("            .Pageable(p => p.PageSizes(new int[] { 20, 30, 50, 100 }).Refresh(true).Messages(model => model.ItemsPerPage(\"条/页\")))\r\n");
                sb.append("            .Scrollable()\r\n");
                sb.append("            .Resizable(f => f.Columns(true))\r\n");
                sb.append("                .DataSource(dataSource => dataSource\r\n");
                sb.append("                .Ajax()\r\n");
                sb.append("                .PageSize(20)\r\n");
                sb.append("                .Read(read => read.Action(\"GetList\", \"" + initcap(tableName) + "\").Data(\"onDataBinding\"))\r\n");
                sb.append("            )\r\n");
                sb.append("        )\r\n");
                sb.append("    </div>\r\n");
                sb.append("</div>\r\n");
                sb.append("<script>\r\n");
                sb.append("    var searchModel = {};\r\n");
                sb.append("    function onDataBinding() {\r\n");
                sb.append("        return searchModel;\r\n");
                sb.append("    }\r\n");
                sb.append("    function search() {\r\n");
                sb.append("        searchModel = {\r\n");
                sb.append("        }\r\n");
                sb.append("        var grid = $(\"#grid\").data(\"kendoGrid\");\r\n");
                sb.append("        grid.dataSource.page(1);\r\n");
                sb.append("    }\r\n");
                sb.append("    function del(id) {\r\n");
                sb.append("        if (confirm(\"是否确认删除此数据？\")) {\r\n");
                sb.append("            $.post(\"/" + initcap(tableName) + "/Delete\", { id: id }, function () {\r\n");
                sb.append("                var grid = $(\"#grid\").data(\"kendoGrid\");\r\n");
                sb.append("                grid.dataSource.read();\r\n");
                sb.append("            })\r\n");
                sb.append("        }\r\n");
                sb.append("   }\r\n");
                sb.append("</script>\r\n");
                writeStringToFile(index, sb.toString());
            }
            //判断文件是否已经存在
            File edit = new File(path + "/Edit.cshtml");
            if (!checkFile(edit)) {
                //拼接内容字符串
                StringBuffer sb = new StringBuffer();
                sb.append("@model " + initcap(tableName) + "Model\r\n");
                sb.append("@{\r\n");
                sb.append("    ViewBag.Title = \"" + projectTable.getTableDesc() + "\";\r\n");
                sb.append("}\r\n");
                sb.append("<style>\r\n");
                sb.append("    .form-group .field-validation-error ul, .form-group .field-validation-error ul li {\r\n");
                sb.append("        list-style: none;\r\n");
                sb.append("        padding-left: 0;\r\n");
                sb.append("    }\r\n");
                sb.append("    .form-group .field-validation-error ul li {\r\n");
                sb.append("        text-align: center;\r\n");
                sb.append("    }\r\n");
                sb.append("</style>\r\n");
                sb.append("<input type=\"hidden\" value=\"" + initcap(tableName) + "Page\" id=\"menutag\" />\r\n");
                sb.append("@using (Html.BeginForm(\"Edit\", \"" + initcap(tableName) + "\"))\r\n");
                sb.append("{\r\n");
                sb.append("    <div class=\"cont-header form-inline\">\r\n");
                sb.append("        <div class=\"pull-left\">\r\n");
                sb.append("            @ViewBag.Title\r\n");
                sb.append("        </div>\r\n");
                sb.append("        <div class=\"pull-right\">\r\n");
                sb.append("            <a href=\"@Url.Action(\"Index\",\"" + initcap(tableName) + "\")\" class=\"k-button\">取消</a>\r\n");
                sb.append("            <button type=\"submit\" class=\"k-button k-primary\">保存</button>\r\n");
                sb.append("        </div>\r\n");
                sb.append("    </div>\r\n");
                sb.append("    <div class=\"box box-solid\">\r\n");
                sb.append("        <div class=\"box-body\">\r\n");
                sb.append("            <div class=\"row\">\r\n");
                sb.append("                <div class=\"col-lg-6 form-horizontal col-sm-offset-3\">\r\n");

                for (ProjectTableProperty ptp : projectTablePropertyList) {
                    String codeType = ptp.getCodeType();
                    if ("DateTime".equals(codeType)) {//时间类型
                        sb.append("                <div class=\"form-group\">\r\n");
                        sb.append("                    @Html.LabelFor(p => p." + initcap(ptp.getENName()) + ", \"" + ptp.getCNName() + "：\", new { @class = \"col-sm-2 control-label\" })\r\n");
                        sb.append("                    <div class=\"col-sm-8\">\r\n");
                        sb.append("                        @if (Model.Id > 0)\r\n");
                        sb.append("                        {@(Html.Kendo().DateTimePicker()\r\n");
                        sb.append("                            .Name(\"" + initcap(ptp.getENName()) + "\")\r\n");
                        sb.append("                            .Value(Model." + initcap(ptp.getENName()) + ")\r\n");
                        sb.append("                            .HtmlAttributes(new { required = \"required\", style = \"width: 100%\", title = \"datetimepicker\" })\r\n");
                        sb.append("                            .DateInput()\r\n");
                        sb.append("                        )}\r\n");
                        sb.append("                        else\r\n");
                        sb.append("                        {@(Html.Kendo().DateTimePicker()\r\n");
                        sb.append("                            .Name(\"" + initcap(ptp.getENName()) + "\")\r\n");
                        sb.append("                            .Value(DateTime.Now)\r\n");
                        sb.append("                            .HtmlAttributes(new { required = \"required\", style = \"width: 100%\", title = \"datetimepicker\" })\r\n");
                        sb.append("                            .DateInput()\r\n");
                        sb.append("                        )}\r\n");
                        sb.append("                    </div>\r\n");
                        sb.append("                </div>\r\n");
                    } else if ("int".equals(codeType)) {//int
                        sb.append("                <div class=\"form-group\">\r\n");
                        sb.append("                    @Html.LabelFor(p => p." + initcap(ptp.getENName()) + ", \"" + ptp.getCNName() + "：\", new { @class = \"col-sm-2 control-label\" })\r\n");
                        sb.append("                    <div class=\"col-sm-8\">\r\n");
                        sb.append("                    @(Html.Kendo().TextBoxFor(p => p." + initcap(ptp.getENName()) + ").HtmlAttributes(new { placeholder = \"请输入" + ptp.getCNName() + "\", " + (ptp.getIsNull() == 1 ? "" : "required = \"required\",") + " validationmessage = \"请输入" + ptp.getCNName() + "\", style = \"width:100%;\", type = \"number\" }))\r\n");
                        sb.append("                    @Html.ValidationMessageFor(p => p." + initcap(ptp.getENName()) + ")\r\n");
                        sb.append("                    </div>\r\n");
                        sb.append("                </div>\r\n");
                    } else {
                        sb.append("                <div class=\"form-group\">\r\n");
                        sb.append("                    @Html.LabelFor(p => p." + initcap(ptp.getENName()) + ", \"" + ptp.getCNName() + "：\", new { @class = \"col-sm-2 control-label\" })\r\n");
                        sb.append("                    <div class=\"col-sm-8\">\r\n");
                        sb.append("                    @(Html.Kendo().TextBoxFor(p => p." + initcap(ptp.getENName()) + ").HtmlAttributes(new { placeholder = \"请输入" + ptp.getCNName() + "\", " + (ptp.getIsNull() == 1 ? "" : "required = \"required\",") + " validationmessage = \"请输入" + ptp.getCNName() + "\", style = \"width:100%;\", type = \"text\" }))\r\n");
                        sb.append("                    @Html.ValidationMessageFor(p => p." + initcap(ptp.getENName()) + ")\r\n");
                        sb.append("                    </div>\r\n");
                        sb.append("                </div>\r\n");
                    }
                }
                sb.append("                <div class=\"form-group\">\r\n");
                sb.append("                    @(Html.ValidationSummary(\"\", new { @class = \"field-validation-error\", style = \"color:red;\" }))\r\n");
                sb.append("                </div>\r\n");
                sb.append("                </div>\r\n");
                sb.append("            </div>\r\n");
                sb.append("        </div>\r\n");
                sb.append("    </div>\r\n");
                sb.append("    @Html.HiddenFor(p => p.Id)\r\n");
                sb.append("}\r\n");
                sb.append("<script>\r\n");
                sb.append("    var validator = $(\"form\").kendoValidator().data(\"kendoValidator\");\r\n");
                sb.append("</script>\r\n");
                sb.append("\r\n");
                writeStringToFile(edit, sb.toString());
            }
            //修改csproj
            String csprojPath = "E:\\myself\\project\\park_management\\SP.Web\\SP.Web.csproj";
            String changeContent = "<Content Include=\"Views\\"+initcap(tableName)+"\\Edit.cshtml\" />\r\n";
            changeContent += "    <Content Include=\"Views\\"+initcap(tableName)+"\\Index.cshtml\" />\r\n";
            String key = "\"Views\\" + initcap(tableName) + "\\";
            ModifyCsproj.modifyCsprojContent(csprojPath,changeContent,key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建文件目录
     *
     * @param path
     * @return
     */
    public static void checkPath(String path) {
        File file = new File(path);
        if (!file.exists() || !file.isDirectory()) {
            file.mkdirs();
        }
    }

    /**
     * 判断文件是否存在
     *
     * @param file
     * @return
     */
    public static boolean checkFile(File file) {

        //return (file.exists() && !file.isDirectory());
        return false;
    }

    /**
     * 把输入字符串的首字母改成大写
     *
     * @param str
     * @return
     */
    public static String initcap(String str) {
        char[] ch = str.toCharArray();
        if (ch[0] >= 'a' && ch[0] <= 'z') {
            ch[0] = (char) (ch[0] - 32);
        }
        return getCamelStr(new String(ch));
    }

    // 例：user_name --> userName
    public static String getCamelStr(String s) {
        while (s.indexOf("_") > 0) {
            int index = s.indexOf("_");
            // System.out.println(s.substring(index+1, index+2).toUpperCase());
            s = s.substring(0, index) + s.substring(index + 1, index + 2).toUpperCase() + s.substring(index + 2);
        }
        return s;
    }

    /**
     * 带BOM的UTF-8文档
     * @param file
     * @param content
     */
    public static void writeStringToFile(File file,String content){
        try {
            byte[] uft8bom={(byte)0xef,(byte)0xbb,(byte)0xbf};
            String res = new String(uft8bom,"UTF-8");
            FileUtils.writeStringToFile(file, res + content,"UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
